package effectiveJava.myEnum;

import com.dycong.common.api_design.sign.encrypt.StringUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by dycong on 2017/9/4.
 */
public enum Operation {
    PLUS("+") {
        public double apply(double x, double y) {
            return x + y;
        }
    },
    MINUS("-") {
        public double apply(double x, double y) {
            return x - y;
        }
    },
    TIMES("*") {
        public double apply(double x, double y) {
            return x * y;
        }
    },
    DIVIDE("/") {
        public double apply(double x, double y) {
            return x / y;
        }
    };;

    /*todo 在枚举类型中声明一个抽象方法，并在特定的常量的类主体中，用具体的方法覆盖每个常量的抽象方法，这种方法被称为特定于常量的方法实现*/
    public abstract double apply(double x, double y);


    private Operation(String symbol) {
        this.symbol = symbol;
    }

    private final String symbol;
    private static final Map<String, Operation> stringToEnum = new HashMap<String, Operation>();

    static { // Initialize map from constant name to enum constant
        for (Operation op : values())
            stringToEnum.put(op.toString(), op);
    }

    /*todo 如果在枚举类型中覆盖了toString()方法，要考虑编写一个fromString方法，将定制的字符串表示法变为相应的枚举*/
    public static Operation fromString(String symbol) {
        return stringToEnum.get(symbol);
    }

    /*todo 通过 valueOf()获得枚举时如果没有对应的枚举常量会抛异常，可以加一个包含判断*/
    public static boolean contains(String name) {
        if (!StringUtils.isEmpty(name)) {
            /*todo values()为继承自 Enum 的方法*/
            Operation[] operations = values();
            for (Operation o : operations) {
                /*todo 必有值调用equals(),name()为继承自 Enum 的方法,返回枚举常量的字符串形式*/
                if (o.name().equals(name)) {
                    return true;
                }
            }

        }
        return false;
    }

    @Override
    public String toString() {
        return symbol;
    }

    public static void main(String[] args) {
        double x = Double.parseDouble("10");
        double y = Double.parseDouble("20");
        for (Operation op : Operation.values())
            System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y));
    }
}
